package org.taobao.ibatiside.ui.wizard;

import java.beans.PropertyChangeEvent;

import org.apache.commons.lang.StringUtils;
import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.beans.BeansObservables;
import org.eclipse.core.databinding.conversion.IConverter;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.databinding.EMFDataBindingContext;
import org.eclipse.emf.databinding.EMFObservables;
import org.eclipse.emf.databinding.EMFUpdateValueStrategy;
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wb.swt.SWTResourceManager;
import org.taobao.ibatiside.model.mapperv2.GeneralStatement;
import org.taobao.ibatiside.model.mapperv2.Mapperv2Package;
import org.taobao.ibatiside.model.mapperv2.Select;
import org.taobao.ibatiside.model.mapperv2.Statement;
import org.taobao.ibatiside.ui.binding.StringToIntegerConverter;
import org.taobao.ibatiside.ui.binding.UniqueValidator;
import org.taobao.ibatiside.ui.util.MiscHelper;

public class StatementGeneralComposite extends PageComposite {
	private static final String[] RESULTSETTYPE_LITERALS = {"SCROLL_INSENSITIVE","FORWARD_ONLY","SCROLL_SENSITIVE"};
	Button btnNeedParameter;
	Button btnNeedResult;
	Button btnNeedDaoPage;
	Button btnFormatContent;
	Text textTimeout;
	Binding timeoutBinding;
	Text textStatementId;
	Binding idBinding;
	Text textXmlResultName;
	Binding xmlNameBinding;
	Button btnRemapResults;
	Binding remapResultsBinding;
	Text textFetchSize;
	Binding fetchSizeBinding;
	Combo comboResultSetType;
	Binding resultsetTypeBinding;
	public StatementGeneralComposite(Composite parent, int style,
			BatisCommonPage page) {
		super(parent, style, page);
	}
	@Override
	public void doNotifyChanged(Notification notification) {
		
	}

	@Override
	protected void doPropertyChange(PropertyChangeEvent evt) {
		if (BatisSettingModel.K_DTP_STMT.equals(evt.getPropertyName())){
			//update statement id of Model by naming convention
		}else if (BatisSettingModel.K_STATEMENT.equals(evt.getPropertyName())){
			String guess_id = MiscHelper.reduceStatementId(model);
			GeneralStatement stmt = (GeneralStatement) evt.getNewValue();
			if (StringUtils.isNotBlank(guess_id)){
				stmt.setId(guess_id);
			}
			checkAttributesEnable(stmt);
			dynamicBinding(stmt);
		}
	}

	private void dynamicBinding(GeneralStatement stmt) {
		EMFDataBindingContext bctx = hostPage.getBindingContext();
		MiscHelper.disposeBinding(timeoutBinding);
		MiscHelper.disposeBinding(idBinding);
		MiscHelper.disposeBinding(fetchSizeBinding);
		MiscHelper.disposeBinding(remapResultsBinding);
		MiscHelper.disposeBinding(resultsetTypeBinding);
		MiscHelper.disposeBinding(xmlNameBinding);
		EMFUpdateValueStrategy strategy = new EMFUpdateValueStrategy();
		strategy.setAfterConvertValidator(new UniqueValidator());
		idBinding = bctx.bindValue(SWTObservables.observeText(textStatementId,SWT.FocusOut), EMFObservables.observeValue(stmt, stmt.eClass().getEStructuralFeature(Mapperv2Package.GENERAL_STATEMENT__ID)), strategy, null);
		
		IObservableValue ob_txt_timeout = SWTObservables.observeText(textTimeout, SWT.Modify);
		IObservableValue ob_model_timeout = EMFObservables.observeValue(stmt, stmt.eClass().getEStructuralFeature(Mapperv2Package.GENERAL_STATEMENT__TIMEOUT));
		strategy = new EMFUpdateValueStrategy();
		strategy.setConverter(new StringToIntegerConverter());
		timeoutBinding = bctx.bindValue(ob_txt_timeout, ob_model_timeout, strategy,null);
		
		if (!(stmt instanceof Select || stmt instanceof Statement)){
			return;
		}
		ISWTObservableValue ob_txt_fetch_size = SWTObservables.observeText(textFetchSize, SWT.Modify);
		IObservableValue ob_model_fs = EMFObservables.observeValue(stmt, stmt.eClass().getEStructuralFeature(stmt instanceof Select ? Mapperv2Package.SELECT__FETCH_SIZE : Mapperv2Package.STATEMENT__FETCH_SIZE));
		fetchSizeBinding = bctx.bindValue(ob_txt_fetch_size, ob_model_fs, strategy, null);
		
		ISWTObservableValue ob_txt_xmlname = SWTObservables.observeText(textXmlResultName, SWT.Modify);
		IObservableValue ob_model_xmlname = EMFObservables.observeValue(stmt, stmt.eClass().getEStructuralFeature(stmt instanceof Select ? Mapperv2Package.SELECT__XML_RESULT_NAME : Mapperv2Package.STATEMENT__XML_RESULT_NAME));
		xmlNameBinding = bctx.bindValue(ob_txt_xmlname, ob_model_xmlname);
		
		ISWTObservableValue ob_btn_remap = SWTObservables.observeSelection(btnRemapResults);
		IObservableValue ob_model_remap = EMFObservables.observeValue(stmt, stmt.eClass().getEStructuralFeature(stmt instanceof Select ? Mapperv2Package.SELECT__REMAP_RESULTS : Mapperv2Package.STATEMENT__REMAP_RESULTS));
		remapResultsBinding = bctx.bindValue(ob_btn_remap, ob_model_remap);
		
		ISWTObservableValue ob_combo_rstype = SWTObservables.observeText(comboResultSetType);
		
		IObservableValue ob_model_rstype = EMFObservables.observeValue(stmt, stmt.eClass().getEStructuralFeature(stmt instanceof Select ? Mapperv2Package.SELECT__RESULT_SET_TYPE : Mapperv2Package.STATEMENT__RESULT_SET_TYPE));
		resultsetTypeBinding = bctx.bindValue(ob_combo_rstype, ob_model_rstype);
	}
	private void checkAttributesEnable(GeneralStatement stmt) {
		if (textXmlResultName != null){
			textXmlResultName.setEnabled(stmt instanceof Select || stmt instanceof Statement);
		}
		if (btnRemapResults != null){
			btnRemapResults.setEnabled(stmt instanceof Select || stmt instanceof Statement);
		}
		if (textFetchSize != null){
			textFetchSize.setEnabled(stmt instanceof Select || stmt instanceof Statement);
		}
		if (comboResultSetType != null){
			comboResultSetType.setEnabled(stmt instanceof Select || stmt instanceof Statement);
		}
	}

	@Override
	protected void createContent() {
		setLayout(new GridLayout(1, false));
		Group group = new Group(this, SWT.NONE);
		GridData gd_group = new GridData(SWT.FILL, SWT.CENTER, true, false, 1,
				1);
		gd_group.heightHint = 80;
		group.setLayoutData(gd_group);
		group.setText("Options");
		group.setBounds(0, 0, 70, 84);
		group.setLayout(new GridLayout(4, false));

		btnNeedParameter = new Button(group, SWT.CHECK);
		btnNeedParameter.setText("Need Parameter");

		btnNeedResult = new Button(group, SWT.CHECK);
		btnNeedResult.setText("Output Result");

		btnNeedDaoPage = new Button(group, SWT.CHECK);
		btnNeedDaoPage.setText("DAO Support");

		btnFormatContent = new Button(group, SWT.CHECK);
		btnFormatContent.setText("Format Content");
		btnFormatContent.setSelection(true);

		Group group_1 = new Group(this, SWT.NONE);
		FormLayout fl_group_1 = new FormLayout();
		fl_group_1.spacing = 5;
		group_1.setLayout(fl_group_1);
		group_1.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		group_1.setText("Attributes");
		group_1.setBounds(0, 0, 70, 84);
		
		Label lblId = new Label(group_1, SWT.NONE);
		lblId.setAlignment(SWT.RIGHT);
		FormData fd_lblId = new FormData();
		fd_lblId.left = new FormAttachment(0, 12);
		lblId.setLayoutData(fd_lblId);
		lblId.setText("ID");
		
		textStatementId = new Text(group_1, SWT.BORDER);
		fd_lblId.top = new FormAttachment(textStatementId, 3, SWT.TOP);
		fd_lblId.right = new FormAttachment(textStatementId, -6);
		FormData fd_textStatementId = new FormData();
		fd_textStatementId.right = new FormAttachment(40);
		fd_textStatementId.top = new FormAttachment(0);
		fd_textStatementId.left = new FormAttachment(0, 68);
		textStatementId.setLayoutData(fd_textStatementId);
		
		Label label = new Label(group_1, SWT.NONE);
		label.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED));
		FormData fd_label = new FormData();
		fd_label.top = new FormAttachment(lblId, 0, SWT.TOP);
		fd_label.left = new FormAttachment(textStatementId, 4);
		label.setLayoutData(fd_label);
		label.setText("*");
		
		Label lblNewLabel = new Label(group_1, SWT.NONE);
		lblNewLabel.setAlignment(SWT.RIGHT);
		FormData fd_lblNewLabel = new FormData();
		fd_lblNewLabel.right = new FormAttachment(lblId, 0, SWT.RIGHT);
		lblNewLabel.setLayoutData(fd_lblNewLabel);
		lblNewLabel.setText("Fetch Size");
		
		textFetchSize = new Text(group_1, SWT.BORDER);
		fd_lblNewLabel.top = new FormAttachment(textFetchSize, 3, SWT.TOP);
		FormData fd_textFetchSize = new FormData();
		fd_textFetchSize.top = new FormAttachment(textStatementId, 6);
		fd_textFetchSize.left = new FormAttachment(textStatementId, 0, SWT.LEFT);
		textFetchSize.setLayoutData(fd_textFetchSize);
		
		Label lblResultsetType = new Label(group_1, SWT.NONE);
		FormData fd_lblResultsetType = new FormData();
		fd_lblResultsetType.bottom = new FormAttachment(lblNewLabel, 0, SWT.BOTTOM);
		fd_lblResultsetType.left = new FormAttachment(textFetchSize, 25);
		lblResultsetType.setLayoutData(fd_lblResultsetType);
		lblResultsetType.setText("Resultset Type");
		
		comboResultSetType = new Combo(group_1, SWT.NONE);
		comboResultSetType.setItems(RESULTSETTYPE_LITERALS);
		FormData fd_comboResultSetType = new FormData();
		fd_comboResultSetType.right = new FormAttachment(60);
		fd_comboResultSetType.bottom = new FormAttachment(textFetchSize, 0, SWT.BOTTOM);
		fd_comboResultSetType.left = new FormAttachment(lblResultsetType, 11);
		comboResultSetType.setLayoutData(fd_comboResultSetType);
		
		Label lblTimeout = new Label(group_1, SWT.NONE);
		FormData fd_lblTimeout = new FormData();
		fd_lblTimeout.top = new FormAttachment(lblNewLabel, 16);
		fd_lblTimeout.right = new FormAttachment(lblId, 0, SWT.RIGHT);
		lblTimeout.setLayoutData(fd_lblTimeout);
		lblTimeout.setText("Timeout");
		
		textTimeout = new Text(group_1, SWT.BORDER);
		FormData fd_textTimeout = new FormData();
		fd_textTimeout.bottom = new FormAttachment(lblTimeout, 0, SWT.BOTTOM);
		fd_textTimeout.left = new FormAttachment(textStatementId, 0, SWT.LEFT);
		textTimeout.setLayoutData(fd_textTimeout);
		
		btnRemapResults = new Button(group_1, SWT.CHECK);
		FormData fd_btnRemapResults = new FormData();
		fd_btnRemapResults.bottom = new FormAttachment(lblTimeout, 0, SWT.BOTTOM);
		fd_btnRemapResults.right = new FormAttachment(textStatementId, 0, SWT.RIGHT);
		btnRemapResults.setLayoutData(fd_btnRemapResults);
		btnRemapResults.setText("Remap Results");
		
		Label lblXmlResultName = new Label(group_1, SWT.NONE);
		FormData fd_lblXmlResultName = new FormData();
		fd_lblXmlResultName.top = new FormAttachment(lblTimeout, 16);
		fd_lblXmlResultName.left = new FormAttachment(lblId, 0, SWT.LEFT);
		lblXmlResultName.setLayoutData(fd_lblXmlResultName);
		lblXmlResultName.setText("Xml Result Name");
		
		textXmlResultName = new Text(group_1, SWT.BORDER);
		FormData fd_textXmlResultName = new FormData();
		fd_textXmlResultName.right = new FormAttachment(40);
		fd_textXmlResultName.bottom = new FormAttachment(lblXmlResultName, 0, SWT.BOTTOM);
		fd_textXmlResultName.left = new FormAttachment(lblXmlResultName, 6);
		textXmlResultName.setLayoutData(fd_textXmlResultName);

	}
	@Override
	protected void doBinding(EMFDataBindingContext bindingContext) {
		super.doBinding(bindingContext);
		ISWTObservableValue ob_g_need_parameter = SWTObservables.observeSelection(btnNeedParameter);
		IObservableValue ob_model_need_parameter = BeansObservables.observeValue(model, BatisSettingModel.K_PARAMETER_REQUIRED);
		bindingContext.bindValue(ob_g_need_parameter, ob_model_need_parameter);
		
		ISWTObservableValue ob_g_need_result = SWTObservables.observeSelection(btnNeedResult);
		IObservableValue ob_model_need_result = BeansObservables.observeValue(model, BatisSettingModel.K_RESULT_REQUIRED);
		bindingContext.bindValue(ob_g_need_result, ob_model_need_result);
		
		ISWTObservableValue ob_g_need_dao = SWTObservables.observeSelection(btnNeedDaoPage);
		IObservableValue ob_model_need_dao = BeansObservables.observeValue(model, BatisSettingModel.K_DAO_PAGE_REQUIRED);
		bindingContext.bindValue(ob_g_need_dao, ob_model_need_dao);
		
		ISWTObservableValue ob_g_need_format = SWTObservables.observeSelection(btnFormatContent);
		IObservableValue ob_model_need_format = BeansObservables.observeValue(model, BatisSettingModel.K_BEAUTIFIER_XML);
		bindingContext.bindValue(ob_g_need_format, ob_model_need_format);
	}
}
